<template>
  <div>
    <el-form :model="searchForm" label-width="90px" :validate-on-rule-change="false">
      <el-form-item label="车牌号" required v-if="shouldShowField('vno')">
        <el-input v-bind="getFieldConfig('vno')" v-model="searchForm.vno" placeholder="请输入车牌号"></el-input>
      </el-form-item>
      <el-form-item label="车牌颜色" required v-if="shouldShowField('vcoTypes')">
        <el-select v-model="searchForm.vco" filterable v-bind="getFieldConfig('vcoTypes')">
          <el-option v-for="item in props.vcoTypes" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="起始时间" required v-if="shouldShowField('qryBtm')">
        <el-date-picker
          v-bind="getFieldConfig('qryBtm')"
          v-model="searchForm.qryBtm"
          type="datetime"
          value-format="YYYY-MM-DD HH:mm:ss"
          placeholder="请选择轨迹起始时间"
          :shortcuts="shortcuts('start')"
          style="width: 100%"
          @change="handleChangeTime($event, 'start')"
          :disabled-date="disabledFutureDate"
        ></el-date-picker>
      </el-form-item>
      <el-form-item label="结束时间" required v-if="shouldShowField('qryEtm')">
        <el-date-picker
          v-bind="getFieldConfig('qryEtm')"
          v-model="searchForm.qryEtm"
          type="datetime"
          value-format="YYYY-MM-DD HH:mm:ss"
          placeholder="请选择轨迹结束时间"
          :shortcuts="shortcuts('end')"
          style="width: 100%"
          @change="handleChangeTime($event, 'end')"
          :disabled-date="disabledFutureDate"
        ></el-date-picker>
      </el-form-item>
      <el-form-item label="始发坐标" v-if="shouldShowField('startLonlat')">
        <el-input
          v-bind="getFieldConfig('startLonlat')"
          v-model="searchForm.startLonlat"
          placeholder="请选择始发地"
          @click="handlePointFocus('start')"
          clearable
        ></el-input>
      </el-form-item>
      <el-form-item label="目的坐标" v-if="shouldShowField('endLonlat')">
        <el-input
          v-bind="getFieldConfig('endLonlat')"
          v-model="searchForm.endLonlat"
          placeholder="请选择目的地"
          @click="handlePointFocus('end')"
          clearable
        ></el-input>
      </el-form-item>
      <div class="stop-time-box" v-if="shouldShowField('parkMins')">
        停车间隔统计
        <el-input
          v-bind="getFieldConfig('parkMins')"
          v-model="searchForm.parkMins"
          type="text"
          style="width: 140px; padding: 0 12px"
          @input="handleParkMinsInput"
          @change="handleParkMinsChange"
        ></el-input>
        分钟以上
      </div>
      <el-button class="search-btn" type="primary" style="width: 100%" @click="handleSearchClick" :loading="loading">
        查询
      </el-button>
    </el-form>
    <PointMap ref="pointMapRef" @submit="onSubmit"></PointMap>
  </div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { validateCarNum } from "../utils/validate";
import { ElMessage } from "element-plus";
import PointMap from "./PointMap.vue";
import { formatDateTime } from "../utils/time";

type ObjType = {
  isShow?: boolean;
  [props: string]: any;
};

interface Props {
  vcoTypes: {
    label: string;
    value: string;
  }[]; // 可根据实际数据结构替换 any 为更具体的类型
  searchConfig?: {
    vno?: ObjType;
    vcoTypes?: ObjType;
    qryBtm?: ObjType;
    qryEtm?: ObjType;
    startLonlat?: ObjType;
    endLonlat?: ObjType;
    parkMins?: ObjType;
  };
}

// 使用 withDefaults 模式
const props = withDefaults(defineProps<Props>(), {
  vcoTypes: (): { label: string; value: string }[] => [],
  searchConfig: () => ({
    vno: {},
    vcoTypes: {},
    qryBtm: {},
    qryEtm: {},
    startLonlat: {},
    endLonlat: {},
    parkMins: {}
  })
});

// 定义emit函数
const emit = defineEmits(["search"]);

const loading = ref(false);

// 表单数据
const searchForm = ref({
  vno: "冀EV8778",
  vco: "2",
  qryBtm: "2025-11-05 00:00:00",
  qryEtm: "2025-11-06 00:00:00",
  startLonlat: "",
  endLonlat: "",
  parkMins: "10"
});

// 辅助函数，判断item是否显示
const shouldShowField = (field: keyof typeof props.searchConfig) => {
  return props.searchConfig[field]?.isShow !== false; // 默认显示，除非明确设置为false
};

// 辅助函数来获取字段的配置
const getFieldConfig = (field: keyof typeof props.searchConfig) => {
  return props.searchConfig[field] || {};
};

// 标点组件ref
const pointMapRef = ref<InstanceType<typeof PointMap> | null>(null);

/**
 * 始发坐标、目的坐标打开地图选择经纬度
 */
const handlePointFocus = (type: any) => {
  pointMapRef.value?.openMap(type);
};
// 选择坐标系
const onSubmit = data => {
  if (data.type === "start") {
    searchForm.value.startLonlat = data.lnglat.lng + "," + data.lnglat.lat;
  }
  if (data.type === "end") {
    searchForm.value.endLonlat = data.lnglat.lng + "," + data.lnglat.lat;
  }
};

// #region 时间选择器配置
const shortcuts = (type: "start" | "end") => {
  return [
    createShortcut("最近6小时", date => date.setTime(date.getTime() - 3600 * 1000 * 6), type),
    createShortcut("最近12小时", date => date.setTime(date.getTime() - 3600 * 1000 * 12), type),
    createShortcut("最近一天", date => date.setTime(date.getTime() - 3600 * 1000 * 24), type),
    createShortcut("最近二天", date => date.setTime(date.getTime() - 3600 * 1000 * 24 * 2), type),
    createShortcut("最近三天", date => date.setTime(date.getTime() - 3600 * 1000 * 24 * 3), type)
  ];
};

/**
 * 生成时间快捷选项
 * @param type - 时间类型('start'开始时间或'end'结束时间)
 * @returns 返回包含快捷选项的数组
 */
const createShortcut = (text: string, timeDelta: (date: Date) => void, type: "start" | "end") => {
  return {
    text,
    value: () => {
      const end = new Date();
      const start = new Date();
      timeDelta(start);
      searchForm.value.qryBtm = formatDateTime(start);
      searchForm.value.qryEtm = formatDateTime(end);
      return type === "start" ? searchForm.value.qryBtm : searchForm.value.qryEtm;
    }
  };
};

/**
 * 处理时间选择变更事件
 * @param {string} value - 新选择的时间值
 * @param {string} type - 时间类型('start'表示开始时间，'end'表示结束时间)
 * @description 验证时间范围有效性，确保开始时间不大于结束时间
 * 1. 空值直接返回
 * 2. 根据类型确定操作的时间字段
 * 3. 获取当前开始和结束时间进行比较
 * 4. 如果时间范围无效则显示错误并重置对应字段
 */
// 定义常量提高可维护性
const MAX_TIME_RANGE_HOURS = 72;
const MILLISECONDS_PER_HOUR = 1000 * 60 * 60;

const handleChangeTime = (value: string | Date, type: "start" | "end") => {
  if (!value) return;

  const field = type === "start" ? "qryBtm" : "qryEtm";
  const currentStartTime = searchForm.value.qryBtm;
  const currentEndTime = searchForm.value.qryEtm;

  // 根据类型确定新的时间值
  const newStartTime = type === "start" ? value : currentStartTime;
  const newEndTime = type === "end" ? value : currentEndTime;

  if (newStartTime && newEndTime) {
    // 尝试转换为Date对象并验证有效性
    const startDate = new Date(newStartTime);
    const endDate = new Date(newEndTime);

    // 计算时间差
    const timeDiff = Math.abs(endDate.getTime() - startDate.getTime());
    const hoursDiff = timeDiff / MILLISECONDS_PER_HOUR;

    // 检查时间顺序和范围
    if (startDate >= endDate) {
      ElMessage.error(type === "start" ? "起始时间不能大于等于结束时间" : "结束时间不能小于等于起始时间");
      searchForm.value[field] = "";
    } else if (hoursDiff > MAX_TIME_RANGE_HOURS) {
      ElMessage.error(`时间范围不能超过${MAX_TIME_RANGE_HOURS}小时`);
      searchForm.value[field] = "";
    }
  }
};

// #endregion

// 禁用未来日期
const disabledFutureDate = (date: Date) => {
  return date > new Date();
};

// #region 处理停车间隔时长
// 添加处理parkMins变化的方法
const handleParkMinsInput = (e: string) => {
  // 实时过滤非数字字符
  searchForm.value.parkMins = e.replace(/[^0-9]/g, "");
};
const handleParkMinsChange = (value: string) => {
  // 处理空值情况
  if (!value) {
    searchForm.value.parkMins = "10";
    return;
  }

  // 转换为整数
  const intValue = parseInt(value);

  // 验证范围
  if (intValue < 10) {
    // this.$message.warning('最小值不能小于10')
    searchForm.value.parkMins = "10";
  } else if (intValue > 10000) {
    // this.$message.warning('最大值不能超过10000')
    searchForm.value.parkMins = "10000";
  } else {
    searchForm.value.parkMins = intValue.toString();
  }
};
// #endregion 处理停车间隔时长

/**
 * 处理搜索按钮点击事件
 * 1. 验证车牌号是否为空
 * 2. 验证车牌号格式
 * 3. 触发search事件
 */
const handleSearchClick = () => {
  const { vno, qryBtm, qryEtm } = searchForm.value;
  const validations = [
    { condition: !vno?.trim(), message: "请输入车牌号" },
    { condition: !validateCarNum(vno), message: "请输入正确的车牌号" },
    { condition: !qryBtm, message: "请选择轨迹起始时间" },
    { condition: !qryEtm, message: "请选择轨迹结束时间" }
  ];

  const failedValidation = validations.find(v => v.condition);
  if (failedValidation) {
    ElMessage.error(failedValidation.message);
    return;
  }

  // 使用emit函数触发事件
  emit("search", { ...searchForm.value });
};

const setSearchForm = (params: any) => {
  searchForm.value = { ...searchForm.value, ...params };
};

defineExpose({
  loading: (status: boolean) => {
    loading.value = status;
  },
  searchForm: { ...searchForm.value },
  setSearchForm
});
</script>
<style lang="scss" scoped>
.stop-time-box {
  color: #606266;
}
.search-btn {
  margin-top: 20px;
}
</style>
